import fs from "fs-extra";
import util, { LogType, config, exec, log } from "../util";
import { Transformer, UiFile } from ".";
import { ScaffoldType } from "../declare";
import path from 'node:path';
import type { CopyOptions } from 'mem-fs-editor'
import * as memFs from 'mem-fs'
import * as memFsEditor from 'mem-fs-editor'


export class Ui2Wx extends Transformer {
  private app!: UiFile
  constructor(public src: string, public dest: string) {
    super(src, dest);
  }

  init() {
    let appSrc = path.join(this.src, 'app.ui');
    if (!fs.existsSync(appSrc)) {
      log.error('未找到app.ui文件');
      return false;
    }
    let appDest = path.join(this.dest, 'app' + config.ext.wxa);
    let app = new UiFile(appSrc, appDest, true);
    log.msg(LogType.READ, 'app.ui配置');
    if (!app.config || !app.config.pages || app.config.pages.length === 0) {
      log.error('app.ui未配置pages');
      return false;
    }
    this.app = app;
    return true;
  }

  async transform() {
    if (this.initSuccess) {
      await this.writeApp();
      await this.writePages();
      await this.writeStatic();
      await this.writePackage();
      await this.npmInstall();
      this.done();
    }
  }

  async writeApp() {
    if (fs.existsSync(this.dest)) {
      fs.emptyDirSync(this.dest);
      log.msg(LogType.DELETE, this.dest);
    }
    await this.app.writeFile('app' + config.ext.wxa);
  }

  async writePages() {
    let pages = this.app.pages, pageSrc, page;
    for (let i = 0; i < pages.length; i++) {
      pageSrc = path.join(this.src, pages[i] + config.ext.ui);
      if (!fs.existsSync(pageSrc)) {
        log.error(`未找到页面文件${pageSrc}`);
        continue;
      }
      let pageDest = path.join(this.dest, pages[i] + config.ext.wxp);
      page = new UiFile(pageSrc, pageDest);
      await page.writeFile(pages[i] + config.ext.wxp);
    }
  }

  async writeStatic() {
    // console.log(__dirname, __filename);
    let srcStaticPath = path.join(
      __dirname,
      `../scaffold/project/application/static`
    );
    let destStaticPath = path.join(this.dest, 'static');
    fs.copy(srcStaticPath, destStaticPath);
    log.msg(LogType.WRITE, 'static目录');
  }

  writePackage() {
    const store = memFs.create();
    const fsEditor = memFsEditor.create(store);
    let proName = path.basename(this.dest);
    let options = {
      proName: proName,
      projectPath: this.dest,
      projectType: 'application',
      proNameToCamelCase: proName,
      title: proName,
      appId: 'touristappid',
      description: 'TouchUI-小程序',
      prefix: 'ui',
      useExample: false,
      useGlobalStyle: false,
      useGlobalLayout: false,
      dest: 'dist',
      npmScope: '',
      npmDest: 'dist/packages',
      gitUrl: '',
      author: '',
      prefixStr: '',
      npmScopeStr: '',
      projectTypeTitle: '小程序',
      options: {
        ProjectType: { Component: 'component', Application: 'application' }
      }
    };
    fsEditor.copyTpl(
      util.getScaffoldPath(
        ScaffoldType.Project,
        'common'
      ),
      this.dest,
      options,
      {},
      {
        globOptions: {
          dot: true
        }
      } as CopyOptions
    );

    return fsEditor.commit().then(() => {
      log.msg(LogType.WRITE, `package.json"`);
    });
  }

  async npmInstall() {
    log.newline();
    log.msg(LogType.RUN, '命令：npm install');
    log.msg(LogType.INFO, '安装中, 请耐心等待...');
    await exec('npm', ['install'], true, {
      cwd: this.dest
    });
  }

  done() {
    log.msg(LogType.COMPLETE, 'TouchUI 工程已转换为小程序工程');
  }

}
